public class TestAnimal {
    public static void main(String[] args) {
        //创建子类之前，会先创建父类，并且调用父类不带参数的构造方法
        Dog d = new Dog("旺财","黑色");
        d.name = "旺财";
        d.breath();
        d.color = "黄色";
        d.bark();
        Animal a = new Animal("测试");
//        a.color = "红色";//父类的范围比子类小，子类中存在的，父类不存在
        Fish f = new Fish();
        f.name = "小花";
        f.breath();
    }
}

class Animal {
    String name;
    //由于创建子类的是需要调用不带参数的构造函数，但是写了带参数的构造函数之后，就不会再创建不带参数的构造函数了
    Animal(String name) {
        this.name = name;
        System.out.println("-------------------->动物被创建!<---------------------");
    }
    Animal() {}
    public void breath() {
        System.out.println(name+"正在喘气");
    }
}

class Fish extends Animal {
    //如果父类没有不带参数的构造函数，子类需要手动构造
    public Fish() {
//        int a = 10;
        //手动构造，而且super必须在构造函数的第一行
//        super("小");
    }
    //子类中可以写一个和父类相同的方法，来覆盖父类
    public void breath() {
        super.breath();
        System.out.println(name+"正在吐泡泡");
    }
}

class Dog extends Animal {
    String color;
    //需要手动调用父类的带参数的构造方法
    public Dog(String name,String color) {
        super(name);
        this.color = color;
    }
    public void bark() {
        System.out.println(name+":颜色为"+color);
    }
}
